package com.nokia.example3dgame;

import javax.microedition.m3g.*;

public class PlayerModel {

	// initial camera position
	private static final float X_POS = 0.0f;

	private static final float Y_POS = 0.4f;

	private static final float Z_POS = 2.0f;

	//	 translation and rotation increments
	private static final float ANGLE_INCR = 5.0f; // degrees

	private static final float MOVE_INCR = 0.1f;

	//for examining the camera's (x,y,z) position
	private Transform trans = new Transform();

	private float[] transMat = new float[16];

	private float xCoord, yCoord, zCoord;

	//for storing the camera's current y- rotations
	private float yAngle;

	private Transform rotTrans = new Transform();

	private Group transGroup;

	private Camera cam;

	//	 booleans for remembering key presses
	private boolean upPressed = false;

	private boolean downPressed = false;

	private boolean leftPressed = false;

	private boolean rightPressed = false;

	public PlayerModel(int width, int height) {
		cam = new Camera();
		float aspectRatio = ((float) width) / ((float) height);
		cam.setPerspective(70.0f, aspectRatio, 0.1f, 50.0f);
		cam.postRotate(-2.0f, 1.0f, 0, 0); // apply x-axis rotations to camera
		// transGroup handles both camera translation and y-axis rotations
		transGroup = new Group(); // no initial rotation
		trans.postTranslate(X_POS, Y_POS, Z_POS);
		transGroup.setTransform(trans);
		transGroup.addChild(cam);
		// store initial rotation
		
		
		
		yAngle = 0.0f;
	}

	public Group getCameraGroup() {
		return transGroup;
	}

	public Camera getCamera() {
		return cam;
	}

	public void setKeysPressed(boolean leftPressed, boolean rightPressed,
			boolean upPressed, boolean downPressed) {
		this.upPressed = upPressed;
		this.downPressed = downPressed;
		this.leftPressed = leftPressed;
		this.rightPressed = rightPressed;
	}

	public void updatePosition() {
		if (upPressed || downPressed) {
			updateMove();
		} else if (leftPressed || rightPressed) {
			updateRotation();
		}
	}

	private void updateMove() {
		float[] pos = getPosition();

		transGroup.getTransform(trans);
		if (upPressed) { // move forward
			trans.postTranslate(0, 0, -MOVE_INCR);
		} else { // move backwards
			trans.postTranslate(0, 0, MOVE_INCR);
		}
		transGroup.setTransform(trans);

	}

	private void updateRotation() {
		if (leftPressed) { // rotate left around the y-axis
			rotTrans.postRotate(ANGLE_INCR, 0, 1.0f, 0);
			yAngle += ANGLE_INCR;
		} else { // rotate right around the y-axis
			rotTrans.postRotate(-ANGLE_INCR, 0, 1.0f, 0);
			yAngle -= ANGLE_INCR;
		}

		// angle values are modulo 360 degrees
		if (yAngle >= 360.0f) {
			yAngle -= 360.0f;
		} else if (yAngle <= -360.0f) {
			yAngle += 360.0f;
		}

		// apply the y-axis rotation to transGroup
		storePosition();
		trans.setIdentity();
		trans.postTranslate(xCoord, yCoord, zCoord);
		trans.postRotate(yAngle, 0, 1.0f, 0);
		transGroup.setTransform(trans);
	}

	private void storePosition() {
		// extract the current (x,y,z) position from transGroup
		transGroup.getCompositeTransform(trans);

		trans.get(transMat);
		xCoord = transMat[3];
		yCoord = transMat[7];
		zCoord = transMat[11];
	} // end of storePosition()

	public float[] getDirection() {
		float[] zVec = { 0, 0, -1.0f, 0 };
		rotTrans.transform(zVec);
		return new float[] { zVec[0], zVec[1], zVec[2] };
	}

	public float[] getPosition() {
		storePosition();
		return new float[] { xCoord, yCoord, zCoord };
	}

}